package com.wxapp.dispatch.service.service.impl;

import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wxapp.common.base.util.bean.SpringUtils;
import com.wxapp.common.constant.base.IBaseService;
import com.wxapp.common.constant.pojo.vm.ResultVm;
import com.wxapp.common.util.check.CheckUtil;
import com.wxapp.common.util.condition.ConditionUtil;
import com.wxapp.common.util.copy.CopyUtil;
import com.wxapp.common.util.random.RandomUtil;
import com.wxapp.dispatch.api.pojo.entity.DispatchDO;
import com.wxapp.dispatch.api.enums.DispatchStatusEnum;
import com.wxapp.dispatch.api.pojo.vo.dispatch.QDispatchAddVo;
import com.wxapp.dispatch.api.pojo.vo.dispatch.QDispatchVo;
import com.wxapp.dispatch.api.pojo.vo.dispatch.QDispatchPageVo;
import com.wxapp.dispatch.api.pojo.vo.dispatch.QDispatchUpdateVo;
import com.wxapp.dispatch.api.pojo.vm.dispatch.PDispatchDetailVm;
import com.wxapp.dispatch.api.pojo.vm.dispatch.PDispatchPageVm;
import com.wxapp.dispatch.service.mapper.DispatchMapper;
import com.wxapp.dispatch.service.service.DispatchService;
import com.wxapp.dispatch.service.util.JobUtil;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lgl
 * @Description
 * @Datetime 2023/5/26 18:01
 * @Modified By
 */
@Service
@RequiredArgsConstructor
public class DispatchServiceImpl extends IBaseService implements DispatchService {
    private final DispatchMapper dispatchMapper;
    private final JobUtil jobUtil;

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public ResultVm<String> add(QDispatchAddVo vm) throws SchedulerException {
        try {
            var dispatch = CopyUtil.copyObjectNew(vm, DispatchDO::new, (s, r) -> {
                r.setCode(RandomUtil.getUUID());
                r.setOpen(false);
                r.setDispatchStatus(DispatchStatusEnum.PAUSE);
                return null;
            });
            Object  classBean = SpringUtils.getBean(vm.getClassNames());
            dispatch.setClassNames(classBean.getClass().getName());
            dispatchMapper.insert(dispatch);
            var dispatchVm = CopyUtil.copyObjectNew(dispatch, QDispatchVo::new, null);
            if (dispatch.getOpen()) {
                jobUtil.addOrUpdateJob(List.of(dispatchVm));
            }
        } catch (Exception e) {
            return error("没有找到类信息");
        }
        return success();
    }

    @Override
    public ResultVm<PDispatchDetailVm> detail(String id) {
        var dispatchDO = dispatchMapper.selectById(id);
        return success(CopyUtil.copyObjectNew(dispatchDO, PDispatchDetailVm::new, null));
    }

    @Override
    public ResultVm<Page<PDispatchPageVm>> page(QDispatchPageVo vm) {
        Map<SFunction<DispatchDO, ?>, SqlKeyword> condition = new HashMap<>();
        condition.put(DispatchDO::getName, SqlKeyword.LIKE);
        var page = ConditionUtil.getPage(vm, DispatchDO.class);
        var conditions = ConditionUtil.getSCondition(DispatchDO::new, vm, PDispatchPageVm.class, condition,null);
        conditions.le(CheckUtil.isNotNullObject(vm.getEndTime()), DispatchDO::getLastTime,vm.getEndTime());
        conditions.lt(CheckUtil.isNotNullObject(vm.getStartTime()),DispatchDO::getLastTime,vm.getStartTime());
        var doPage = dispatchMapper.selectPage(page, conditions);
        return success(CopyUtil.copyPage(doPage, PDispatchPageVm::new, null));
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public ResultVm<String> update(QDispatchUpdateVo vm) throws SchedulerException {
        var dispatchDO = dispatchMapper.selectById(vm.getId());
        CopyUtil.copyObject(vm, dispatchDO, (s, r) -> {
            r.setClassNames(s.getClassNames());
            return null;
        });
        dispatchMapper.updateById(dispatchDO);
        var dispatchVm = CopyUtil.copyObjectNew(dispatchDO, QDispatchVo::new, null);
        jobUtil.addOrUpdateJob(List.of(dispatchVm));
        return success();
    }

    @Override
    public ResultVm<String> delete(String id) {
        var dispatchDO = dispatchMapper.selectById(id);
        dispatchDO.setStatus(false);
        dispatchMapper.updateById(dispatchDO);
        var dispatchVm = CopyUtil.copyObjectNew(dispatchDO, QDispatchVo::new, null);
        jobUtil.removeOrStopJob(dispatchVm);
        return success();
    }

    @Override
    public ResultVm<String> pauseOrRes(String id, Boolean isPause) throws SchedulerException {
        var dispatchDO = dispatchMapper.selectById(id);
        dispatchDO.setOpen(!isPause);
        if (isPause) {
            dispatchDO.setDispatchStatus(DispatchStatusEnum.PAUSE);
        } else {
            dispatchDO.setDispatchStatus(DispatchStatusEnum.RUN);
        }
        dispatchMapper.updateById(dispatchDO);
        var dispatchVm = CopyUtil.copyObjectNew(dispatchDO, QDispatchVo::new, null);
        if (isPause) {
            jobUtil.removeOrStopJob(dispatchVm);
        } else {
            jobUtil.addOrUpdateJob(List.of(dispatchVm));
        }
        return success();
    }
}
